use bevy::prelude::*;
use crate::animate::Animator;
use crate::class::StyleCommand;
use crate::GameState;
use crate::ui::game_map::{GameDirection, MapPanelRelate, Moving, Player, ui_game_map};

pub struct PlayGamePlugin;

impl Plugin for PlayGamePlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(OnEnter(GameState::GameEnter), ui_game_map)
            .add_systems(Update, animator_state.run_if(in_state(GameState::GameEnter)))
            .add_systems(Update, move_player.run_if(in_state(GameState::Gaming)));
    }
}

fn animator_state(
    mut state: ResMut<NextState<GameState>>,
    query: Query<&Animator, With<MapPanelRelate>>,
) {
    let animator = query.single();
    if animator.get_exec_index() == 1 && animator.get_is_finish(){
        state.set(GameState::Gaming);   
    }
}

fn move_player(
    mut commands: Commands,
    mut query_player: Query<(Entity, &mut Player)>,
    button_event: Res<ButtonInput<KeyCode>>,
) {
    for (entity, mut player) in query_player.iter_mut() {
        if player.is_player1() {
            if button_event.just_pressed(KeyCode::KeyW) {
                player.moving_stack.push(GameDirection::Up);
            }
            if button_event.just_pressed(KeyCode::KeyS) {
                player.moving_stack.push(GameDirection::Down);
            }
            if button_event.just_pressed(KeyCode::KeyA) {
                player.moving_stack.push(GameDirection::Left);
            }
            if button_event.just_pressed(KeyCode::KeyD) {
                player.moving_stack.push(GameDirection::Right);
            }
            if button_event.just_released(KeyCode::KeyW) {
                player.moving_stack.retain(|&x| x != GameDirection::Up);
            }
            if button_event.just_released(KeyCode::KeyS) {
                player.moving_stack.retain(|&x| x != GameDirection::Down);
            }
            if button_event.just_released(KeyCode::KeyA) {
                player.moving_stack.retain(|&x| x != GameDirection::Left);
            }
            if button_event.just_released(KeyCode::KeyD) {
                player.moving_stack.retain(|&x| x != GameDirection::Right);
            }
            commands.set_style(entity, ui_update_tank);
        } else if player.is_player2() {
            if button_event.just_pressed(KeyCode::ArrowUp) {
                player.moving_stack.push(GameDirection::Up);
            }
            if button_event.just_pressed(KeyCode::ArrowDown) {
                player.moving_stack.push(GameDirection::Down);
            }
            if button_event.just_pressed(KeyCode::ArrowLeft) {
                player.moving_stack.push(GameDirection::Left);
            }
            if button_event.just_pressed(KeyCode::ArrowRight) {
                player.moving_stack.push(GameDirection::Right);
            }
            if button_event.just_released(KeyCode::ArrowUp) {
                player.moving_stack.retain(|&x| x != GameDirection::Up);
            }
            if button_event.just_released(KeyCode::ArrowDown) {
                player.moving_stack.retain(|&x| x != GameDirection::Down);
            }
            if button_event.just_released(KeyCode::ArrowLeft) {
                player.moving_stack.retain(|&x| x != GameDirection::Left);
            }
            if button_event.just_released(KeyCode::ArrowRight) {
                player.moving_stack.retain(|&x| x != GameDirection::Right);
            }
            commands.set_style(entity, ui_update_tank);
        }
    }
}

pub fn ui_update_tank(
    mut transform: Mut<Transform>,
    mut layout: Mut<TextureAtlas>,
    mut tank: Mut<Moving>,
    player: Mut<Player>,
) {
    let idx = (layout.index + 1) % 2;
    if let Some(dir) = player.moving_stack.last() {
        tank.direction = *dir;
        match tank.direction {
            GameDirection::Up => {
                layout.index = idx;
                transform.translation.y += tank.speed as f32;
            }
            GameDirection::Down => {
                layout.index = 2 + idx;
                transform.translation.y -= tank.speed as f32;
            }
            GameDirection::Left => {
                layout.index = 4 + idx;
                transform.translation.x -= tank.speed as f32;
            }
            GameDirection::Right => {
                layout.index = 6 + idx;
                transform.translation.x += tank.speed as f32;
            }
        }
    }
}
